iT邦幫忙

2023 iThome 鐵人賽

DAY 17
1
Modern Web

那些你可能要知道的前端知識系列 第 17

【day17】JavaScript "this"

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20230920/20148303MhE9E6GMFD.png


In most cases, the value of this is determined by how a function is called.

MDN對this的定義是「this在大多數的狀況下,會因為function如何被呼叫,而有所不同

this會以哪些呼叫方式來判斷

全域環境,直接使用this呼叫

如過是純粹調用this,那麼this將會指向到全域的window物件上

console.log(this) // 輸出 Window 物件

console.log(this === window); // true
//瀏覽器中window也屬於全域物件

this.a = "AL"
console.log(window.a)
console.log(a)
//都會輸出 AL

另外要特別注意的是,如果在「嚴格模式」下,會自動禁止this指定為全域物件,因此this值預設會是undefined

function f2() {
  "use strict"; 
  return this;
}

f2() // undefined

物件方法調用this

當一個函數作為物件的方法被呼叫時,this 指向該物件
在範例程式碼,getName被呼叫時,它的this會是指向a的物件

const a  = {
    name: "AL",
    getName: function () {
        console.log(this.name)
    }
}
a.getName() // 輸出 AL
  • 定義了a物件,裡面有name屬性和getName方法,這邊的this.name會訪問到物件中的name屬性
  • 這邊的this指向當前的物件
  • a.getName被呼叫時,this指向當前的物件a,因此會this.name輸出AL

建構式的調用

使用new來調用一個函式時,會建立一個物件,this將會指到這個物件上

function a(name){
    this.name = name
}

const b = new a("AL")
console.log(b.name) // 輸出 AL
  • 在這個範例中,呼叫a的時候使用new的方式,因此會建立一個新的物件,並回傳給b
  • 新建立的物件,會透過傳入的AL參數,將它當作新物件name屬性的值,因此b.name會輸出AL

DOM事件處理

在DOM事件處理中,this通常會指到觸發事件的元素

button.addEventListener('click', function() {
  console.log(this);  //  button element
});

箭頭函式 Arror Function (ES6)

JavaScript ES6 新增的箭頭函數沒有自己的this,箭頭函式的this會由它的外層函式繼承,如果找不到它的外層函式,就會一層層往外找,它會找到全域的this值Window物件

const a = () => this
console.log(a()) // 輸出 Window 物件

最後再整理 this 是什麼

  • function被呼叫時是用 new 的方式,this就是被新構建出來的物件
  • function被呼叫時已經存在於物件中,this即是那個物件
  • function如果是被call()/apply()/bind()方法直接「指定」this,那麼this將是指定的物件
  • 在DOM事件中的this,這個this就會是被觸發到事件的元素
  • 上面列出的方法外,this值會是全域的Window物件,若是在"嚴格模式"中,this會是undefined

參考文章
鐵人賽:JavaScript 的 this 到底是誰?
JS 核心觀念筆記 - 什麼是 this
MDN-this
Explain.this


上一篇
【day16】bind、call 、apply 的區別
下一篇
【day18】JavaScript の 嚴格模式(Strict mode)
系列文
那些你可能要知道的前端知識30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言